import { FileChangeUtil } from "./FileChangeUtil";
import { Main } from "../Main";
import { ConfigUtil } from "./ConfigUtil";
import * as fs from "fs";
import { SyncResExecUtil } from "./SyncResExecUtil";

/**
 * 资源同步，找出需要操作的文件，只找不操作
 * @author 赵占涛
 */
export class SyncResInfoUtil {
    /**
     * 找出需要操作的文件
     */
    static getChangeList(type: "normal" | "ios" | "android", cb: (exportList: string[], deleteList: string[]) => void) {
        FileChangeUtil.changed(Main.codePath + "Resources/cocosstudio/cocosstudio/", (sourceChange: string[], sourceAdd: string[], sourceDelete: string[]) => {
            let resTmpPath = type == "normal" ? "res/" : (type == "ios" ? "resPlatform/resIos/" : "resPlatform/resAndroid/");

            FileChangeUtil.changed(Main.codePath + "Resources/" + resTmpPath, (outputChange: string[], outputAdd: string[], outputDelete: string[]) => {
                // console.log(sourceChange, sourceAdd, sourceDelete);
                // console.log(outputChange, outputAdd, outputDelete);

                // 需要导出的
                let needExportObj: { [key: string]: true } = {};
                // 需要删除的
                let needDeleteObj: { [key: string]: true } = {};
                this.funcSourceChange(needExportObj, needDeleteObj, sourceChange);
                this.funcSourceChange(needExportObj, needDeleteObj, sourceAdd);
                this.funcSourceDelete(needExportObj, needDeleteObj, sourceDelete);
                this.funcOutputChange(type, needExportObj, needDeleteObj, outputChange);
                this.funcOutputChange(type, needExportObj, needDeleteObj, outputAdd);
                this.funcOutputDelete(type, needExportObj, needDeleteObj, outputDelete);

                cb(Object.keys(needExportObj), Object.keys(needDeleteObj));
            }, this.signOtherCalcOutput.bind(this));
        }, this.signOtherCalcSource.bind(this));
    }
    /** 源文件的额外签名计算函数 */
    static signOtherCalcSource(file: string): string {
        let mergeDir = "";
        let noPkmPvr = "";
        let compress = false;
        if (file.endsWith(".png")) {
            mergeDir = this.getMergeDir(file);
            if (mergeDir == "") {
                compress = SyncResExecUtil.checkCompress(file);
            } else {
                compress = SyncResExecUtil.checkCompress(mergeDir);
                if (this.isNoPkmPvr(file)) {
                    noPkmPvr = "|noPkmPvr";
                }
            }
        } else if (file.endsWith(".jpg")) {
            compress = SyncResExecUtil.checkCompress(file);
        }
        return mergeDir + "|" + compress + noPkmPvr;
    }
    /** 目标文件的额外签名计算函数 */
    static signOtherCalcOutput(file: string): string {
        let mergeDir = "";
        let noPkmPvr = "";
        let compress = false;
        if (file.endsWith(".png") || file.endsWith(".pkm") || file.endsWith(".pkm@alpha") || file.endsWith(".pvr.ccz")) {
            mergeDir = this.getMergeDir(file.replace(".png", "/").replace(".pvr.ccz", "/").replace(".pkm@alpha", "/").replace(".pkm", "/"));
            if (mergeDir == "") {
                compress = file.endsWith(".png") && SyncResExecUtil.checkCompress(file);
            } else {
                compress = file.endsWith(".png") && SyncResExecUtil.checkCompress(mergeDir);
                if (this.isNoPkmPvr(mergeDir)) {
                    noPkmPvr = "|noPkmPvr";
                }
            }
        } else if (file.endsWith(".plist")) {
            mergeDir = this.getMergeDir(file.replace(".plist", "/"));
        }
        return mergeDir + "|" + compress + noPkmPvr;
    }
    /** 源文件更改（或添加）的处理 */
    static funcSourceChange(needExportObj: { [key: string]: true }, needDeleteObj: { [key: string]: true }, sourceChange: string[]) {
        // 如果源文件变更了，则需要导出
        for (let i = 0; i < sourceChange.length; i++) {
            const file = sourceChange[i];
            if (file.endsWith(".png") || file.endsWith(".jpg")) {
                let mergeDir = this.getMergeDir(file);
                if (mergeDir != "") {
                    needExportObj[mergeDir] = true;
                } else {
                    needExportObj[file] = true;
                }
            } else if (!file.endsWith(".udf") && !file.endsWith(".db")) {
                needExportObj[file] = true;
            }
        }
    }
    /** 源文件被删的处理 */
    static funcSourceDelete(needExportObj: { [key: string]: true }, needDeleteObj: { [key: string]: true }, sourceChange: string[]) {
        for (let i = 0; i < sourceChange.length; i++) {
            const file = sourceChange[i];
            if (file.endsWith(".png") || file.endsWith(".jpg")) {
                let mergeDir = this.getMergeDir(file);
                if (mergeDir != "") {
                    // 合图的一张源图被删，如果合图的其它文件还在，就重新合图，如果不在，就删除导出的合图
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + mergeDir)) {
                        needExportObj[mergeDir] = true;
                    } else {
                        needDeleteObj[mergeDir.substr(0, mergeDir.length - 1) + ".plist"] = true;
                        needDeleteObj[mergeDir.substr(0, mergeDir.length - 1) + ".png"] = true;
                        needDeleteObj[mergeDir.substr(0, mergeDir.length - 1) + ".pkm"] = true;
                        needDeleteObj[mergeDir.substr(0, mergeDir.length - 1) + ".pkm@alpha"] = true;
                        needDeleteObj[mergeDir.substr(0, mergeDir.length - 1) + ".pvr.ccz"] = true;
                    }
                } else {
                    needDeleteObj[file] = true;
                }
            } else if (!file.endsWith(".udf") && !file.endsWith(".db")) {
                if (file.endsWith(".csd")) {
                    let luaFile = file.replace(".csd", ".lua");
                    needDeleteObj[luaFile] = true;
                } else {
                    needDeleteObj[file] = true;
                }
            }
        }
    }
    /** 输出文件更改（或添加）的处理 */
    static funcOutputChange(type: "normal" | "ios" | "android", needExportObj: { [key: string]: true }, needDeleteObj: { [key: string]: true }, outputChange: string[]) {
        let resTmpPath = type == "normal" ? "res/" : (type == "ios" ? "resPlatform/resIos/" : "resPlatform/resAndroid/");
        for (let i = 0; i < outputChange.length; i++) {
            const file = outputChange[i];
            if (type == "ios" && file.endsWith(".pvr.ccz")) {
                let mergeDir = this.getMergeDir(file.replace(".pvr.ccz", "/"));
                if (mergeDir != "" && fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + mergeDir) && !this.isNoPkmPvr(mergeDir)) {
                    needExportObj[mergeDir] = true;
                } else {
                    needDeleteObj[file] = true;
                    let plistFile = file.replace(".pvr.ccz", ".plist");
                    if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + plistFile)) {
                        needDeleteObj[plistFile] = true;
                    }
                }
            } else if (type == "android" && file.endsWith(".pkm")) {
                let mergeDir = this.getMergeDir(file.replace(".pkm", "/"));
                if (mergeDir != "" && fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + mergeDir) && !this.isNoPkmPvr(mergeDir)) {
                    needExportObj[mergeDir] = true;
                } else {
                    needDeleteObj[file] = true;
                    if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + file + "@alpha")) {
                        needDeleteObj[file + "@alpha"] = true;
                    }
                    let plistFile = file.replace(".pkm", ".plist");
                    if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + plistFile)) {
                        needDeleteObj[plistFile] = true;
                    }
                }
            } else if (type == "android" && file.endsWith(".pkm@alpha")) {
                let mergeDir = this.getMergeDir(file.replace(".pkm@alpha", "/"));
                if (mergeDir != "" && fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + mergeDir) && !this.isNoPkmPvr(mergeDir)) {
                    needExportObj[mergeDir] = true;
                } else {
                    needDeleteObj[file] = true;
                    if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + file.replace(".pkm@alpha", ".pkm"))) {
                        needDeleteObj[file.replace(".pkm@alpha", ".pkm")] = true;
                    }
                    let plistFile = file.replace(".pkm@alpha", ".plist");
                    if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + plistFile)) {
                        needDeleteObj[plistFile] = true;
                    }
                }
            } else if (file.endsWith(".png")) {
                let mergeDir = this.getMergeDir(file.replace(".png", "/"));
                if (mergeDir != "") {
                    // 是合图
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + mergeDir) && (type == "normal" || this.isNoPkmPvr(mergeDir))) {
                        needExportObj[mergeDir] = true;
                    } else {
                        needDeleteObj[file] = true;
                        let plistFile = file.replace(".png", ".plist");
                        if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + plistFile)) {
                            needDeleteObj[plistFile] = true;
                        }
                    }
                } else {
                    // 是单图
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + file)) {
                        needExportObj[file] = true;
                    } else {
                        needDeleteObj[file] = true;
                    }
                }
            } else if (file.endsWith(".plist")) {
                // 是合图
                let mergeDir = this.getMergeDir(file.replace(".plist", "/"));
                if (mergeDir) {
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + mergeDir)) {
                        needExportObj[mergeDir] = true;
                    } else {
                        needDeleteObj[file] = true;
                        let pngFile = file.replace(".plist", type=="normal"?".png":(type=="ios"?".pvr.ccz":".pkm"));
                        if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + pngFile)) {
                            needDeleteObj[pngFile] = true;
                        }
                        if (type == "android") {
                            if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + file + "@alpha")) {
                                needDeleteObj[file + "@alpha"] = true;
                            }
                        }
                    }
                } else {
                    // 是单文件
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + file)) {
                        needExportObj[file] = true;
                    } else {
                        needDeleteObj[file] = true;
                    }
                }
            } else if (!file.endsWith(".udf") && !file.endsWith(".db")) {
                if (file.endsWith(".lua")) { // lua文件，如果原csd还在，就重新导出，如果不在，就删除lua
                    let csdFile = file.replace(".lua", ".csd");
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + csdFile)) {
                        needExportObj[csdFile] = true;
                    } else {
                        needDeleteObj[file] = true;
                    }
                } else {
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + file)) {
                        needExportObj[file] = true;
                    } else {
                        needDeleteObj[file] = true;
                    }
                }
            }
        }
    }
    /** 输出文件删除的处理 */
    static funcOutputDelete(type: "normal" | "ios" | "android", needExportObj: { [key: string]: true }, needDeleteObj: { [key: string]: true }, outputDelete: string[]) {
        let resTmpPath = type == "normal" ? "res/" : (type == "ios" ? "resPlatform/resIos/" : "resPlatform/resAndroid/");
        for (let i = 0; i < outputDelete.length; i++) {
            const file = outputDelete[i];
            if (type == "ios" && file.endsWith(".pvr.ccz")) {

                let mergeDir = this.getMergeDir(file.replace(".pvr.ccz", "/"));
                if (mergeDir != ""&& fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + mergeDir)) {
                    needExportObj[mergeDir] = true;
                } else {
                    let plistFile = file.replace(".pvr.ccz", ".plist");
                    if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + plistFile)) {
                        needDeleteObj[plistFile] = true;
                    }
                }
            } else if (type == "android" && file.endsWith(".pkm")) {

                let mergeDir = this.getMergeDir(file.replace(".pkm", "/"));
                if (mergeDir != ""&& fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + mergeDir)) {
                    needExportObj[mergeDir] = true;
                } else {
                    if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + file + "@alpha")) {
                        needDeleteObj[file + "@alpha"] = true;
                    }
                    let plistFile = file.replace(".pkm", ".plist");
                    if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + plistFile)) {
                        needDeleteObj[plistFile] = true;
                    }
                }
            } else if (type == "android" && file.endsWith(".pkm@alpha")) {

                let mergeDir = this.getMergeDir(file.replace(".pkm@alpha", "/"));
                if (mergeDir != ""&& fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + mergeDir)) {
                    needExportObj[mergeDir] = true;
                } else {
                    if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + file.replace(".pkm@alpha", ".pkm"))) {
                        needDeleteObj[file.replace(".pkm@alpha", ".pkm")] = true;
                    }
                    let plistFile = file.replace(".pkm@alpha", ".plist");
                    if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + plistFile)) {
                        needDeleteObj[plistFile] = true;
                    }
                }
            } else if (file.endsWith(".png")) {
                let mergeDir = this.getMergeDir(file.replace(".png", "/"));
                if (mergeDir != "") {
                    // 是合图
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + mergeDir)) {
                        console.log("mergeDir need export", file);
                        needExportObj[mergeDir] = true;
                    } else {
                        let plistFile = file.replace(".png", ".plist");
                        if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + plistFile)) {
                            needDeleteObj[plistFile] = true;
                        }
                    }
                } else {
                    // 是单图
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + file)) {
                        needExportObj[file] = true;
                    }
                }
            } else if (file.endsWith(".plist")) {
                // 是合图
                let mergeDir = this.getMergeDir(file.replace(".plist", "/"));
                if (mergeDir) {
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + mergeDir)) {
                        needExportObj[mergeDir] = true;
                    } else {
                        let pngFile = file.replace(".plist", type=="normal"?".png":(type=="ios"?".pvr.ccz":".pkm"));
                        if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + pngFile)) {
                            needDeleteObj[pngFile] = true;
                        }
                        if (type == "android") {
                            if (fs.existsSync(Main.codePath + "Resources/" + resTmpPath + file + "@alpha")) {
                                needDeleteObj[file + "@alpha"] = true;
                            }
                        }
                    }
                } else {
                    // 是单文件
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + file)) {
                        needExportObj[file] = true;
                    }
                }
            } else if (!file.endsWith(".udf") && !file.endsWith(".db")) {
                if (file.endsWith(".lua")) { // lua文件，如果原csd还在，就重新导出
                    let csdFile = file.replace(".lua", ".csd");
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + csdFile)) {
                        needExportObj[csdFile] = true;
                    }
                } else {
                    if (fs.existsSync(Main.codePath + "Resources/cocosstudio/cocosstudio/" + file)) {
                        needExportObj[file] = true;
                    }
                }
            }
        }
    }
    /**
     * 得到合图路径
     * @param png 单个图片的路径
     */
    static getMergeDir(png: string): string {
        for (let i = 0; i < ConfigUtil.MergePicCfg.dirs.length; i++) {
            const dir = ConfigUtil.MergePicCfg.dirs[i];
            if (png.startsWith(dir)) {
                return png.substr(0, png.lastIndexOf("/") + 1);
            }
        }
        return "";
    }
    /**
     * 得到合图是否不导出pkmpvr
     * @param png 单个图片的路径
     */
    static isNoPkmPvr(png: string) {
        for (let i = 0; i < ConfigUtil.NoPkmPvrCfg.dirs.length; i++) {
            const dir = ConfigUtil.NoPkmPvrCfg.dirs[i];
            if (png.startsWith(dir)) {
                return true;
            }
        }
        return false;
    }
}